<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram of a Block and Spring System</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="physics-diagram" width="650" height="450"></canvas>
    <script>
        const canvas = document.getElementById('physics-diagram');
        const ctx = canvas.getContext('2d');

        // Helper function to draw an arrow
        function drawArrow(ctx, fromx, fromy, tox, toy, headlen = 10) {
            const dx = tox - fromx;
            const dy = toy - fromy;
            const angle = Math.atan2(dy, dx);
            ctx.beginPath();
            ctx.moveTo(fromx, fromy);
            ctx.lineTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }
        
        // --- Start Drawing ---
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 2;
        ctx.fillStyle = 'black';

        // 1. Draw the horizontal surface (ground)
        const groundY = 350;
        ctx.beginPath();
        ctx.moveTo(0, groundY);
        ctx.lineTo(650, groundY);
        ctx.stroke();

        // 2. Draw the vertical wall on the right
        const wallX = 600;
        ctx.beginPath();
        ctx.moveTo(wallX, groundY);
        ctx.lineTo(wallX, groundY - 150);
        ctx.stroke();
        // Add hatching to indicate a fixed wall
        for (let i = 0; i < 8; i++) {
            ctx.beginPath();
            ctx.moveTo(wallX, groundY - 140 + i * 20);
            ctx.lineTo(wallX + 20, groundY - 160 + i * 20);
            ctx.stroke();
        }

        // 3. Draw the large block M
        const M_height = 120;
        const M_width = 400;
        const M_x = 100;
        const M_y = groundY - M_height;
        ctx.strokeRect(M_x, M_y, M_width, M_height);
        
        // Label for M
        ctx.font = 'italic 24px "Times New Roman"';
        ctx.fillText('M', M_x + M_width/2 - 50, M_y + M_height/2 + 10);
        
        // 4. Draw the small block m
        const m_height = 50;
        const m_width = 80;
        const m_x = M_x + 280;
        const m_y = M_y - m_height;
        ctx.strokeRect(m_x, m_y, m_width, m_height);

        // Label for m
        ctx.fillText('m', m_x + m_width/2 - 10, m_y + m_height/2 + 10);

        // 5. Draw the spring system
        const springAttachPostX = M_x + 10;
        const springY = M_y + 40;
        
        // Spring attachment post
        ctx.beginPath();
        ctx.moveTo(springAttachPostX, M_y);
        ctx.lineTo(springAttachPostX, M_y + 80);
        ctx.moveTo(springAttachPostX - 10, M_y);
        ctx.lineTo(springAttachPostX + 10, M_y);
        ctx.stroke();
        
        // Spring coils
        const springStartX = springAttachPostX;
        const springEndX = m_x - 80;
        const springPlateX = springEndX;
        ctx.beginPath();
        ctx.moveTo(springStartX, springY);
        ctx.lineTo(springStartX + 15, springY);
        // Using Bezier curves to create smooth loops like the drawing
        let x1 = springStartX + 15;
        let x2 = x1 + 25;
        let x3 = x2 + 25;
        let x4 = x3 + 25;
        let y_amp = 18;
        ctx.bezierCurveTo(x1, springY - y_amp, x2, springY - y_amp, x2, springY);
        ctx.bezierCurveTo(x2, springY + y_amp, x3, springY + y_amp, x3, springY);
        ctx.bezierCurveTo(x3, springY - y_amp, x4, springY - y_amp, x4, springY);
        ctx.stroke();
        
        // Spring end plate
        ctx.beginPath();
        ctx.moveTo(springPlateX, springY - 25);
        ctx.lineTo(springPlateX, springY + 25);
        ctx.stroke();

        // 6. Draw the velocity vector for block m
        const arrowY = m_y - 25;
        const arrowStartX = m_x + m_width / 2 + 30;
        const arrowEndX = m_x + m_width / 2 - 30;
        drawArrow(ctx, arrowStartX, arrowY, arrowEndX, arrowY);
        
        // Label for velocity v0
        ctx.font = 'italic 24px "Times New Roman"';
        ctx.fillText('v', arrowEndX - 25, arrowY - 5);
        ctx.font = 'italic 16px "Times New Roman"';
        ctx.fillText('0', arrowEndX - 15, arrowY);

        // 7. Draw the string connecting M to the wall
        // In the diagram, a small platform-like structure connects M to the wall.
        // The problem description says it's a "thin string". We will draw a line.
        const stringY = M_y + 50;
        ctx.beginPath();
        ctx.moveTo(M_x + M_width, stringY);
        ctx.lineTo(wallX, stringY);
        ctx.stroke();

        // 8. Add the caption
        ctx.font = '20px "SimSun"'; // Using a common Chinese font
        ctx.fillStyle = 'black';
        ctx.fillText('力图 3.21.1', 270, groundY + 50);

    </script>
</body>
</html>